using Lzfy_Refund_Service.Models;
using System.Text.Json;
using System.Text.Encodings.Web;
using System.Text.Unicode;

namespace Lzfy_Refund_Service.Services
{
    /// <summary>
    /// 患者数据查询服务实现
    /// </summary>
    public class PatientDataQueryService : IPatientDataQueryService
    {
        private readonly IRedisService _redisService;
        private readonly ILogger<PatientDataQueryService> _logger;
        private readonly JsonSerializerOptions _jsonOptions;
        
        // Redis数据库配置
        private const int DB1 = 1; // 源数据库
        private const int DB2 = 2; // 目标数据库
        private static readonly TimeSpan DB2_EXPIRY = TimeSpan.FromMinutes(20); //20分钟过期 .FromHours(1); // 1小时过期

        public PatientDataQueryService(
            IRedisService redisService,
            ILogger<PatientDataQueryService> logger)
        {
            _redisService = redisService;
            _logger = logger;
            
            // 配置JSON序列化选项
            _jsonOptions = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
            };
        }

        /// <summary>
        /// 根据用户ID查询最新的患者数据并迁移到db2
        /// </summary>
        /// <param name="userId">用户ID（医生ID）</param>
        /// <returns>患者数据查询响应</returns>
        public async Task<PatientDataQueryResponse> QueryAndMigratePatientDataAsync(string userId)
        {
            try
            {
                _logger.LogInformation("开始查询患者数据，用户ID: {UserId}", userId);
                
                // 1. 获取db1中匹配用户ID前缀的所有键
                var pattern = $"{userId}*";
                var matchingKeys = await _redisService.GetKeysAsync(pattern, DB1);
                
                if (!matchingKeys.Any())
                {
                    _logger.LogInformation("未找到匹配的患者数据，用户ID: {UserId}", userId);
                    return new PatientDataQueryResponse
                    {
                        Success = false,
                        Message = "未找到匹配的患者数据"
                    };
                }
                
                _logger.LogInformation("找到 {Count} 条匹配的键，用户ID: {UserId}", matchingKeys.Count, userId);
                
                // 2. 获取所有匹配键的数据，并找到最新的一条
                var latestKey = string.Empty;
                var latestData = string.Empty;
                //DateTime latestDate = DateTime.MaxValue; // 最小日期，找最大的
                DateTime latestDate = DateTime.MinValue; // 最大日期，找最小的
                foreach (var key in matchingKeys)
                {
                    var data = await _redisService.GetAsync(key, DB1);
                    if (string.IsNullOrEmpty(data))
                        continue;
                    
                    try
                    {
                        var patientData = JsonSerializer.Deserialize<PatientVisitData>(data, _jsonOptions);
                        //if (patientData != null && patientData.OutP_DATE < latestDate) // 找最小的
                        if (patientData != null && patientData.OutP_DATE > latestDate)// 找最大的
                        {
                            latestDate = patientData.OutP_DATE;
                            latestKey = key;
                            latestData = data;
                        }
                    }
                    catch (JsonException ex)
                    {
                        _logger.LogWarning(ex, "解析患者数据失败，键: {Key}", key);
                        continue;
                    }
                }
                
                if (string.IsNullOrEmpty(latestKey))
                {
                    _logger.LogWarning("未找到有效的患者数据，用户ID: {UserId}", userId);
                    return new PatientDataQueryResponse
                    {
                        Success = false,
                        Message = "未找到有效的患者数据"
                    };
                }
                
                _logger.LogInformation("找到最新患者数据，键: {Key}, 日期: {Date}", latestKey, latestDate);
                
                // 3. 将数据迁移到db2
                var migrateSuccess = await _redisService.SetAsync(latestKey, latestData, DB2, DB2_EXPIRY);
                if (!migrateSuccess)
                {
                    _logger.LogError("数据迁移到db2失败，键: {Key}", latestKey);
                    return new PatientDataQueryResponse
                    {
                        Success = false,
                        Message = "数据迁移失败"
                    };
                }
                
                _logger.LogInformation("数据迁移到db2成功，键: {Key}", latestKey);
                
                // 4. 从db1删除数据
                var deleteSuccess = await _redisService.DeleteAsync(latestKey, DB1);
                if (!deleteSuccess)
                {
                    _logger.LogWarning("从db1删除数据失败，键: {Key}", latestKey);
                    // 不影响主流程，继续返回数据
                }
                else
                {
                    _logger.LogInformation("从db1删除数据成功，键: {Key}", latestKey);
                }
                
                // 5. 解析并返回数据
                var resultData = JsonSerializer.Deserialize<PatientVisitData>(latestData, _jsonOptions);
                
                _logger.LogInformation("患者数据查询完成，用户ID: {UserId}, 患者: {PatientName}", 
                    userId, resultData?.PatI_NAME);
                
                return new PatientDataQueryResponse
                {
                    Success = true,
                    Message = "查询成功",
                    Data = resultData
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询患者数据异常，用户ID: {UserId}", userId);
                return new PatientDataQueryResponse
                {
                    Success = false,
                    Message = $"查询异常: {ex.Message}"
                };
            }
        }
    }
}